reading datasets
Rows: 180 Columns: 5
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (2): specimen_id, infancy-vac
dbl (3): subject_id, visit, Timepoint
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Rows: 195 Columns: 1
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (1): specimen_id subject_id visit Timepoint infancy_vac
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Rows: 8085 Columns: 9
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (4): Sample_ID, isotype, antigen, isotype_antigen
dbl (5): Plate, visit, dpb, ab_titer_median, lower_limit_of_dectection_median
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Joining, by = "subject_id"
Rows: 31520 Columns: 7
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): isotype, antigen, unit
dbl (3): specimen_id, ab_titer, lower_limit_of_detection
lgl (1): is_antigen_specific
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Joining, by = "specimen_id"
#input_data_1 <- input_data[input_data$isotype_antigen == "IgG3_PT",]
## Setting MFI zero values to lower limit of detection
df_lod_calculated_2020 <- data_2020 %>%
group_by(isotype_antigen) %>%
mutate(lod = min(ab_titer[ab_titer>0]),
MFI_lod = if_else(ab_titer == 0 | is.na(ab_titer) == TRUE, lod, ab_titer)
) %>%
ungroup()
df_d0_median_2020 <- df_lod_calculated_2020 %>%
filter(planned_day_relative_to_boost == 0) %>%
group_by(isotype_antigen) %>%
summarise(
overall_median_d0 = median(MFI_lod),
#overall_iqr_d0 = IQR(MFI_lod)
)
data_2020_new <- left_join(df_lod_calculated_2020 , df_d0_median_2020 , by = "isotype_antigen") %>%
mutate(
ab_titer_median = MFI_lod / overall_median_d0,
#ab_titer_iqr = MFI_lod / overall_iqr_d0
)
#df_d0_median_2020 %>%
#ggplot(aes(log(overall_median_d0), log(overall_iqr_d0))) + geom_point() + theme_ipsum() + geom_smooth()
medians_d0_2020 <- data_2020_new %>%
group_by(isotype_antigen) %>%
filter(planned_day_relative_to_boost == 0) %>%
summarize( median_d0 = median(ab_titer_median)
)
medians_d0_2020
for(select.isotype in c("IgG"))
{
#png(filename=paste0("2020",select.isotype,".png"), width=600, height=700)
#select.isotype_antigen = "IgG1"
plot1 <- data_2020_common %>%
filter(isotype == select.isotype, planned_day_relative_to_boost < 50) %>%
#filter(ab_titer > lower_limit_of_detection)
filter(antigen %in% unique(data_2021_common[data_2021_common$isotype == select.isotype,]$antigen)) %>%
ggplot(., aes(y=ab_titer_median, x=planned_day_relative_to_boost)) +
ggtitle(paste0("2020 Antibody titers (" , select.isotype, ")")) +
geom_point() +
geom_line(aes(group=subject_id),linetype = "dotted")+
labs(x = "Day post boost", y = "Ab titer") +
geom_smooth() +
theme_bw() +
facet_wrap(. ~ antigen, scales = "free", nrow = 1) +
theme(strip.background = element_blank(), strip.placement = "outside") +
scale_y_continuous(trans = 'log2', labels=scaleFUN)
plot(plot1)
#dev.off()
#png(filename=paste0("2021",select.isotype,".png"), width=600, height=700)
plot2 <- data_2021_common %>%
filter(isotype == select.isotype, dpb < 50) %>%
#filter(ab_titer_median < 1) %>%
filter(antigen %in% unique(data_2020_common[data_2020_common$isotype == select.isotype,]$antigen)) %>%
#ggplot(., aes(y=log2(ab_titer_median), x=dpb)) +
ggplot(., aes(y=ab_titer_median, x=dpb)) +
ggtitle(paste0("2021 Antibody titers (" , select.isotype, ")")) +
geom_point() +
geom_line(aes(group=subject_id),linetype = "dotted")+
labs(x = "Day post boost", y = "Ab titer") +
geom_smooth() +
theme_bw() +
facet_wrap(. ~ antigen, scales = "free", nrow = 1) +
theme(strip.background = element_blank(), strip.placement = "outside") +
scale_y_continuous(trans = 'log2', labels=scaleFUN)
plot(plot2)
#dev.off()
}
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'


Ploting in log scale
for(select.isotype in c("IgG1", "IgG2", "IgG3", "IgG4"))
{
#png(filename=paste0("2020",select.isotype,".png"), width=600, height=700)
#select.isotype_antigen = "IgG1"
plot1 <- data_2020_common %>%
filter(isotype == select.isotype, planned_day_relative_to_boost < 50) %>%
filter(antigen %in% c("DT", "FHA", "FIM2/3")) %>%
filter(antigen %in% unique(data_2021_common[data_2021_common$isotype == select.isotype,]$antigen)) %>%
ggplot(., aes(y=(ab_titer_median), x=planned_day_relative_to_boost)) +
ggtitle(paste0("2020 Antibody titers (" , select.isotype, ")")) +
geom_point() +
geom_line(aes(group=subject_id),linetype = "dotted")+
labs(x = "Day post boost", y = "Ab titer") +
geom_smooth() +
theme_bw() +
facet_wrap(. ~ antigen, scales = "free", nrow = 1) +
theme(strip.background = element_blank(), strip.placement = "outside") +
scale_y_continuous(trans = 'log2', labels=scaleFUN)
plot(plot1)
#dev.off()
#png(filename=paste0("2021",select.isotype,".png"), width=600, height=700)
plot2 <- data_2021_common %>%
filter(isotype == select.isotype, dpb < 50) %>%
filter(antigen %in% c("DT", "FHA", "FIM2/3")) %>%
filter(antigen %in% unique(data_2020_common[data_2020_common$isotype == select.isotype,]$antigen)) %>%
#ggplot(., aes(y=log2(ab_titer_median), x=dpb)) +
ggplot(., aes(y=ab_titer_median, x=dpb)) +
ggtitle(paste0("2021 Antibody titers (" , select.isotype, ")")) +
geom_point() +
geom_line(aes(group=subject_id),linetype = "dotted")+
labs(x = "Day post boost", y = "Ab titer") +
geom_smooth() +
theme_bw() +
facet_wrap(. ~ antigen, scales = "free", nrow = 1) +
theme(strip.background = element_blank(), strip.placement = "outside") +
scale_y_continuous(trans = 'log2', labels=scaleFUN)
plot(plot2)
#dev.off()
}
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'








Ploting in log scale
for(select.isotype in c("IgG1", "IgG2", "IgG3", "IgG4"))
{
#png(filename=paste0("2020",select.isotype,".png"), width=600, height=700)
#select.isotype_antigen = "IgG1"
plot1 <- data_2020_common %>%
filter(isotype == select.isotype, planned_day_relative_to_boost < 50) %>%
filter(antigen %in% c("OVA", "PRN", "PT", "TT")) %>%
filter(antigen %in% unique(data_2021_common[data_2021_common$isotype == select.isotype,]$antigen)) %>%
ggplot(., aes(y=(ab_titer_median), x=planned_day_relative_to_boost)) +
ggtitle(paste0("2020 Antibody titers (" , select.isotype, ")")) +
geom_point() +
geom_line(aes(group=subject_id),linetype = "dotted")+
labs(x = "Day post boost", y = "Ab titer") +
geom_smooth() +
theme_bw() +
facet_wrap(. ~ antigen, scales = "free", nrow = 1) +
theme(strip.background = element_blank(), strip.placement = "outside") +
scale_y_continuous(trans = 'log2', labels=scaleFUN)
plot(plot1)
#dev.off()
#png(filename=paste0("2021",select.isotype,".png"), width=600, height=700)
plot2 <- data_2021_common %>%
filter(isotype == select.isotype, dpb < 50) %>%
filter(antigen %in% c("OVA", "PRN", "PT", "TT")) %>%
filter(antigen %in% unique(data_2020_common[data_2020_common$isotype == select.isotype,]$antigen)) %>%
#ggplot(., aes(y=log2(ab_titer_median), x=dpb)) +
ggplot(., aes(y=ab_titer_median, x=dpb)) +
ggtitle(paste0("2021 Antibody titers (" , select.isotype, ")")) +
geom_point() +
geom_line(aes(group=subject_id),linetype = "dotted")+
labs(x = "Day post boost", y = "Ab titer") +
geom_smooth() +
theme_bw() +
facet_wrap(. ~ antigen, scales = "free", nrow = 1) +
theme(strip.background = element_blank(), strip.placement = "outside") +
scale_y_continuous(trans = 'log2', labels=scaleFUN)
plot(plot2)
#dev.off()
}
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'








data_plot_2021_medians_d0 <- data_2021 %>%
group_by(isotype_antigen) %>%
filter(dpb == 0) %>%
summarise(median_d0 = median(ab_titer_median))
data_plot_2021_medians_d0
Plot tail distribution
for(select.isotype in c("IgG"))
{
p1 <- data_2020_common %>%
#filter(antigen %in% unique(data_2021_common))
filter(isotype == select.isotype) %>%
arrange(desc(ab_titer_median)) %>%
ggplot(aes(y=ab_titer_median)) + stat_ecdf(geom = "point")+
labs(y = "Ab titer", x = "Percentile")+ ggtitle(paste0("2020 Antibody titers (" , select.isotype, ")")) + theme_bw() +
facet_wrap(. ~ antigen, scales = "free", nrow = 1) +
scale_y_continuous(trans = 'log2', labels=scaleFUN)
#ggplot(aes(x=ab_titer_median, y=Sample_ID)) + geom_point()
plot(p1)
p1 <- data_2021_common %>%
#filter(antigen %in% unique(data_2020_common)) %>%
filter(antigen %in% unique(data_2020_common[data_2020_common$isotype == select.isotype,]$antigen)) %>%
filter(isotype == select.isotype) %>%
arrange(desc(ab_titer_median)) %>%
ggplot(aes(y=ab_titer_median)) + stat_ecdf(geom = "point")+
labs(y = "Ab titer", x = "Percentile")+ ggtitle(paste0("2021 Antibody titers (" , select.isotype, ")")) + theme_bw() +
facet_wrap(. ~ antigen, scales = "free", nrow = 1) +
scale_y_continuous(trans = 'log2', labels=scaleFUN)
#ggplot(aes(x=ab_titer_median, y=Sample_ID)) + geom_point()
plot(p1)
}


NA
NA
for(select.isotype in c("IgG1", "IgG2", "IgG3", "IgG4"))
{
p1 <- data_2020_common %>%
#filter(antigen %in% unique(data_2021_common))
filter(isotype == select.isotype) %>%
arrange(desc(ab_titer_median)) %>%
ggplot(aes(y=ab_titer_median)) + stat_ecdf(geom = "point")+
labs(y = "Ab titer", x = "Percentile")+ ggtitle(paste0("2020 Antibody titers (" , select.isotype, ")")) + theme_bw() +
facet_wrap(. ~ antigen, scales = "free", nrow = 2) +
scale_y_continuous(trans = 'log2', labels=scaleFUN)
#ggplot(aes(x=ab_titer_median, y=Sample_ID)) + geom_point()
plot(p1)
p2 <- data_2021_common %>%
#filter(antigen %in% unique(data_2020_common)) %>%
filter(antigen %in% unique(data_2020_common[data_2020_common$isotype == select.isotype,]$antigen)) %>%
filter(isotype == select.isotype) %>%
arrange(desc(ab_titer_median)) %>%
ggplot(aes(y=ab_titer_median)) + stat_ecdf(geom = "point")+
labs(y = "Ab titer", x = "Percentile")+ ggtitle(paste0("2021 Antibody titers (" , select.isotype, ")")) + theme_bw() +
facet_wrap(. ~ antigen, scales = "free", nrow = 2) +
scale_y_continuous(trans = 'log2', labels=scaleFUN)
#ggplot(aes(x=ab_titer_median, y=Sample_ID)) + geom_point()
plot(p2)
}








data_2020_common %>%
filter(isotype != "IgE" & planned_day_relative_to_boost==0) %>%
mutate(titer = if_else(ab_titer <= lower_limit_of_detection, 0, ab_titer),
titer_lod = if_else(ab_titer <= lower_limit_of_detection, lower_limit_of_detection, ab_titer),
) %>%
group_by(isotype_antigen) %>%
summarise(median_lod_T= median(titer_lod), median_lod_F= median(titer[titer>0]))
LS0tCnRpdGxlOiAiQWIgdGl0ZXIgZGF0YSBjb21wYXJpc2lvbiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3IgZWNobz1GQUxTRX0KbGlicmFyeSgidGlkeXZlcnNlIikKbGlicmFyeShocmJydGhlbWVzKQpsaWJyYXJ5KGpzb25saXRlKQoKb3B0aW9ucyh3YXJuPS0xKQpgYGAKCgoKIyMgcmVhZGluZyBkYXRhc2V0cwpgYGB7ciBlY2hvPUZBTFNFfQpzZXR3ZCgiL2hvbWUvcHJhbW9kL0RvY3VtZW50cy9jbWlwYl9wcm9qZWN0L2FiX3BsYXRlX25vcm1hbGlzYXRpb24iKQpkYXRhXzIwMjFfbWV0YWRhdGEgPC0gcmVhZF90c3YoIm1ldGFkYXRhX2NtaXBiXzIwMjEuY3N2IikKZGF0YV8yMDIwX21ldGFkYXRhIDwtIHJlYWRfY3N2KCJtZXRhZGF0YV9jbWlwYl8yMDIwLmNzdiIpCgojZGF0YV8yMDIxIDwtIHJlYWRfdHN2KCIyMDIxX2FiX3RpdGVyXzAzMjQyMi50c3YiKSAgJT4lCmRhdGFfMjAyMSA8LSByZWFkX3RzdigiMjAyMV9hYl90aXRlcl8wMzI1MjJfb25lX2xvZC50c3YiKSAgJT4lCiAgIHJlbmFtZShzcGVjaW1lbl9pZCA9IFNhbXBsZV9JRCkgJT4lCiAgICBtdXRhdGUoc3ViamVjdF9pZCA9IHN1YnN0cihzcGVjaW1lbl9pZCwgMSw0KSwKICAgICAgICAgICB2aXNpdCA9IHN1YnN0cihzcGVjaW1lbl9pZCwgOSw5KSwKICAgICAgICAgICBkcGI9IGNhc2Vfd2hlbigKICAgICAgICAgICAgICAgIHZpc2l0ID09IDEgfiAwLAogICAgICAgICAgICAgICAgdmlzaXQgPT0gMiB+IDEsCiAgICAgICAgICAgICAgICB2aXNpdCA9PSAzIH4gMywKICAgICAgICAgICAgICAgIHZpc2l0ID09IDQgfiA3LAogICAgICAgICAgICAgICAgdmlzaXQgPT0gNSB+IDE0LAogICAgICAgICAgICAgICAgdmlzaXQgPT0gNiB+IDMwLAogICAgICAgICAgICAgICAgdmlzaXQgPT0gNyB+IDkwLAogICAgICAgICAgICksCiAgICAgICAgICAgaXNvdHlwZV9hbnRpZ2VuID0gcGFzdGUwKGlzb3R5cGUsIl8iLGFudGlnZW4pCiAgKSAKICAKICAgIApqc29uX3N1YmplY3QgPC0gZnJvbUpTT04oInN1YmplY3QuanNvbiIpCmpzb25fc3BlY2ltZW4gPC0gZnJvbUpTT04oInNwZWNpbWVuLmpzb24iKQpzdWJqZWN0X3NwZWNpbWVuICA8LSBsZWZ0X2pvaW4oanNvbl9zcGVjaW1lbiwganNvbl9zdWJqZWN0KQoKZGF0YV8yMDIwIDwtIHJlYWRfY3N2KCIyMDIwTERfYWJfdGl0ZXIuY3N2IikgJT4lCiAgbGVmdF9qb2luKHN1YmplY3Rfc3BlY2ltZW4pICU+JQogIG11dGF0ZSgKICAgIGFudGlnZW4gPSByZXBsYWNlKGFudGlnZW4sIGFudGlnZW4gPT0nMSUgUEZBIFBUJywgJ1BUJyksCiAgICBpc290eXBlX2FudGlnZW4gPSBwYXN0ZTAoaXNvdHlwZSwiXyIsYW50aWdlbikpCiAgCmRhdGFfMjAyMCA8LSBkYXRhXzIwMjAgJT4lCiAgbXV0YXRlKAogICAgI2xvd2VyX2xpbWl0X29mX2RldGVjdGlvbiA9IGlmX2Vsc2UoaXNvdHlwZV9hbnRpZ2VuID09ICJJZ0dfRkhBIiwgNC42Nzk1MzUsIGxvd2VyX2xpbWl0X29mX2RldGVjdGlvbiksICMjIENvcnJlY3QgTE9EIGZvciBJZ0dfRkhBCiAgICBhYl90aXRlciA9IGlmX2Vsc2UoYWJfdGl0ZXIgPCBsb3dlcl9saW1pdF9vZl9kZXRlY3Rpb24sIGxvd2VyX2xpbWl0X29mX2RldGVjdGlvbiwgYWJfdGl0ZXIpCiAgKQoKYGBgCgojIyMKYGBge3J9CgojaW5wdXRfZGF0YV8xIDwtIGlucHV0X2RhdGFbaW5wdXRfZGF0YSRpc290eXBlX2FudGlnZW4gPT0gIklnRzNfUFQiLF0KIyMgU2V0dGluZyBNRkkgemVybyB2YWx1ZXMgdG8gbG93ZXIgbGltaXQgb2YgZGV0ZWN0aW9uCmRmX2xvZF9jYWxjdWxhdGVkXzIwMjAgPC0gZGF0YV8yMDIwICU+JQogIGdyb3VwX2J5KGlzb3R5cGVfYW50aWdlbikgJT4lCiAgbXV0YXRlKGxvZCA9IG1pbihhYl90aXRlclthYl90aXRlcj4wXSksCiAgICAgICAgIE1GSV9sb2QgPSBpZl9lbHNlKGFiX3RpdGVyID09IDAgfCBpcy5uYShhYl90aXRlcikgPT0gVFJVRSwgbG9kLCBhYl90aXRlcikKICAgICAgICAgKSAlPiUKICB1bmdyb3VwKCkgCgpkZl9kMF9tZWRpYW5fMjAyMCAgPC0gZGZfbG9kX2NhbGN1bGF0ZWRfMjAyMCAlPiUKICBmaWx0ZXIocGxhbm5lZF9kYXlfcmVsYXRpdmVfdG9fYm9vc3QgPT0gMCkgJT4lCiAgZ3JvdXBfYnkoaXNvdHlwZV9hbnRpZ2VuKSAlPiUKICBzdW1tYXJpc2UoCiAgICBvdmVyYWxsX21lZGlhbl9kMCA9IG1lZGlhbihNRklfbG9kKSwKICAgICNvdmVyYWxsX2lxcl9kMCA9IElRUihNRklfbG9kKQogICkgCgoKZGF0YV8yMDIwX25ldyAgIDwtICBsZWZ0X2pvaW4oZGZfbG9kX2NhbGN1bGF0ZWRfMjAyMCAsIGRmX2QwX21lZGlhbl8yMDIwICwgYnkgPSAiaXNvdHlwZV9hbnRpZ2VuIikgJT4lCiAgbXV0YXRlKAogICAgYWJfdGl0ZXJfbWVkaWFuID0gTUZJX2xvZCAvIG92ZXJhbGxfbWVkaWFuX2QwLAogICAgI2FiX3RpdGVyX2lxciA9IE1GSV9sb2QgLyBvdmVyYWxsX2lxcl9kMAogICkKCgojZGZfZDBfbWVkaWFuXzIwMjAgJT4lCiAgI2dncGxvdChhZXMobG9nKG92ZXJhbGxfbWVkaWFuX2QwKSwgbG9nKG92ZXJhbGxfaXFyX2QwKSkpICsgZ2VvbV9wb2ludCgpICsgdGhlbWVfaXBzdW0oKSArIGdlb21fc21vb3RoKCkgCiAgCm1lZGlhbnNfZDBfMjAyMCA8LSBkYXRhXzIwMjBfbmV3ICU+JQogIGdyb3VwX2J5KGlzb3R5cGVfYW50aWdlbikgJT4lCiAgZmlsdGVyKHBsYW5uZWRfZGF5X3JlbGF0aXZlX3RvX2Jvb3N0ID09IDApICU+JQogIHN1bW1hcml6ZSggICAgICAgICAgbWVkaWFuX2QwID0gbWVkaWFuKGFiX3RpdGVyX21lZGlhbikKICAgICAgICAgICAgKQoKbWVkaWFuc19kMF8yMDIwCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CmNvbW1vbl9hbnRpZ2VucyA8LSBpbnRlcnNlY3QoZGF0YV8yMDIwX25ldyRhbnRpZ2VuLCBkYXRhXzIwMjEkYW50aWdlbikKY29tbW9uX2lzb3R5cGVzIDwtIGludGVyc2VjdChkYXRhXzIwMjBfbmV3ICRpc290eXBlLCBkYXRhXzIwMjEkaXNvdHlwZSkKCmRhdGFfMjAyMV9jb21tb24gPC0gZGF0YV8yMDIxICU+JQogIGZpbHRlcihhbnRpZ2VuICVpbiUgY29tbW9uX2FudGlnZW5zICYgaXNvdHlwZSAlaW4lIGNvbW1vbl9pc290eXBlcykgJT4lCiAgbXV0YXRlKGRhdGFzZXQgPSAiMjAyMSIpIAoKZGF0YV8yMDIwX2NvbW1vbiA8LSBkYXRhXzIwMjBfbmV3ICU+JQogIGZpbHRlcihhbnRpZ2VuICVpbiUgY29tbW9uX2FudGlnZW5zICYgaXNvdHlwZSAlaW4lIGNvbW1vbl9pc290eXBlcykgJT4lCiAgbXV0YXRlKGRhdGFzZXQgPSAiMjAyMCIpCiAgCmRhdGFfMjAyMF9jb21tb25fY29udHJvbCA8LSBkYXRhXzIwMjBfY29tbW9uICU+JQogIGZpbHRlcihzdWJqZWN0X2lkICVpbiUgYygnMicsICc4JykpCgpkYXRhXzIwMjFfY29tbW9uX2NvbnRyb2wgPC0gZGF0YV8yMDIxX2NvbW1vbiAlPiUKICBmaWx0ZXIoc3ViamVjdF9pZCAlaW4lIGMoJzE2ODYnLCAnMjYzMScpKQoKI2RhdGFfMjAyMF8yMDIxX2NvbW1vbiA8LSByYmluZChkYXRhXzIwMjBfY29tbW9uLCBkYXRhXzIwMjFfY29tbW9uKQojT3VyIHRyYW5zZm9ybWF0aW9uIGZ1bmN0aW9uCnNjYWxlRlVOIDwtIGZ1bmN0aW9uKHgpIHNwcmludGYoIiUuM2YiLCB4KQpgYGAKCgoKYGBge3J9CmZvcihzZWxlY3QuaXNvdHlwZSBpbiBjKCJJZ0ciKSkKewogIAojcG5nKGZpbGVuYW1lPXBhc3RlMCgiMjAyMCIsc2VsZWN0Lmlzb3R5cGUsIi5wbmciKSwgd2lkdGg9NjAwLCBoZWlnaHQ9NzAwKSAgCiAgCiNzZWxlY3QuaXNvdHlwZV9hbnRpZ2VuID0gIklnRzEiIApwbG90MSA8LSBkYXRhXzIwMjBfY29tbW9uICU+JQogIGZpbHRlcihpc290eXBlID09IHNlbGVjdC5pc290eXBlLCBwbGFubmVkX2RheV9yZWxhdGl2ZV90b19ib29zdCA8IDUwKSAlPiUKICAjZmlsdGVyKGFiX3RpdGVyID4gbG93ZXJfbGltaXRfb2ZfZGV0ZWN0aW9uKQogIGZpbHRlcihhbnRpZ2VuICVpbiUgdW5pcXVlKGRhdGFfMjAyMV9jb21tb25bZGF0YV8yMDIxX2NvbW1vbiRpc290eXBlID09IHNlbGVjdC5pc290eXBlLF0kYW50aWdlbikpICU+JQogIGdncGxvdCguLCBhZXMoeT1hYl90aXRlcl9tZWRpYW4sIHg9cGxhbm5lZF9kYXlfcmVsYXRpdmVfdG9fYm9vc3QpKSArCiAgICBnZ3RpdGxlKHBhc3RlMCgiMjAyMCBBbnRpYm9keSB0aXRlcnMgKCIgLCBzZWxlY3QuaXNvdHlwZSwgIikiKSkgKwogICAgZ2VvbV9wb2ludCgpICsgCiAgICBnZW9tX2xpbmUoYWVzKGdyb3VwPXN1YmplY3RfaWQpLGxpbmV0eXBlID0gImRvdHRlZCIpKwogICAgbGFicyh4ID0gIkRheSBwb3N0IGJvb3N0IiwgeSA9ICJBYiB0aXRlciIpICsgCiAgICBnZW9tX3Ntb290aCgpICsKICAgIHRoZW1lX2J3KCkgKwogICAgZmFjZXRfd3JhcCguIH4gYW50aWdlbiwgc2NhbGVzID0gImZyZWUiLCBucm93ID0gMSkgKwogICAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgc3RyaXAucGxhY2VtZW50ID0gIm91dHNpZGUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gJ2xvZzInLCBsYWJlbHM9c2NhbGVGVU4pCgoKcGxvdChwbG90MSkKI2Rldi5vZmYoKQojcG5nKGZpbGVuYW1lPXBhc3RlMCgiMjAyMSIsc2VsZWN0Lmlzb3R5cGUsIi5wbmciKSwgd2lkdGg9NjAwLCBoZWlnaHQ9NzAwKSAgCnBsb3QyIDwtIGRhdGFfMjAyMV9jb21tb24gJT4lCiAgZmlsdGVyKGlzb3R5cGUgPT0gc2VsZWN0Lmlzb3R5cGUsIGRwYiA8IDUwKSAlPiUKICAjZmlsdGVyKGFiX3RpdGVyX21lZGlhbiA8IDEpICAlPiUKICBmaWx0ZXIoYW50aWdlbiAlaW4lIHVuaXF1ZShkYXRhXzIwMjBfY29tbW9uW2RhdGFfMjAyMF9jb21tb24kaXNvdHlwZSA9PSBzZWxlY3QuaXNvdHlwZSxdJGFudGlnZW4pKSAlPiUKICAjZ2dwbG90KC4sIGFlcyh5PWxvZzIoYWJfdGl0ZXJfbWVkaWFuKSwgeD1kcGIpKSArCiAgZ2dwbG90KC4sIGFlcyh5PWFiX3RpdGVyX21lZGlhbiwgeD1kcGIpKSArCiAgICBnZ3RpdGxlKHBhc3RlMCgiMjAyMSBBbnRpYm9keSB0aXRlcnMgKCIgLCBzZWxlY3QuaXNvdHlwZSwgIikiKSkgKwogICAgZ2VvbV9wb2ludCgpICsgCiAgICBnZW9tX2xpbmUoYWVzKGdyb3VwPXN1YmplY3RfaWQpLGxpbmV0eXBlID0gImRvdHRlZCIpKwogICAgbGFicyh4ID0gIkRheSBwb3N0IGJvb3N0IiwgeSA9ICJBYiB0aXRlciIpICsgCiAgICBnZW9tX3Ntb290aCgpICsKICAgIHRoZW1lX2J3KCkgKwogICAgZmFjZXRfd3JhcCguIH4gYW50aWdlbiwgc2NhbGVzID0gImZyZWUiLCBucm93ID0gMSkgKwogICAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgc3RyaXAucGxhY2VtZW50ID0gIm91dHNpZGUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gJ2xvZzInLCBsYWJlbHM9c2NhbGVGVU4pCgoKcGxvdChwbG90MikKI2Rldi5vZmYoKQp9CmBgYAoKCiMjIFBsb3RpbmcgaW4gbG9nIHNjYWxlCmBgYHtyfQpmb3Ioc2VsZWN0Lmlzb3R5cGUgaW4gYygiSWdHMSIsICJJZ0cyIiwgIklnRzMiLCAiSWdHNCIpKQp7CiAgCiNwbmcoZmlsZW5hbWU9cGFzdGUwKCIyMDIwIixzZWxlY3QuaXNvdHlwZSwiLnBuZyIpLCB3aWR0aD02MDAsIGhlaWdodD03MDApICAKICAKI3NlbGVjdC5pc290eXBlX2FudGlnZW4gPSAiSWdHMSIgCnBsb3QxIDwtIGRhdGFfMjAyMF9jb21tb24gJT4lCiAgZmlsdGVyKGlzb3R5cGUgPT0gc2VsZWN0Lmlzb3R5cGUsIHBsYW5uZWRfZGF5X3JlbGF0aXZlX3RvX2Jvb3N0IDwgNTApICU+JQogIGZpbHRlcihhbnRpZ2VuICVpbiUgYygiRFQiLCAiRkhBIiwgIkZJTTIvMyIpKSAgJT4lCiAgZmlsdGVyKGFudGlnZW4gJWluJSB1bmlxdWUoZGF0YV8yMDIxX2NvbW1vbltkYXRhXzIwMjFfY29tbW9uJGlzb3R5cGUgPT0gc2VsZWN0Lmlzb3R5cGUsXSRhbnRpZ2VuKSkgJT4lCiAgZ2dwbG90KC4sIGFlcyh5PShhYl90aXRlcl9tZWRpYW4pLCB4PXBsYW5uZWRfZGF5X3JlbGF0aXZlX3RvX2Jvb3N0KSkgKwogICAgZ2d0aXRsZShwYXN0ZTAoIjIwMjAgQW50aWJvZHkgdGl0ZXJzICgiICwgc2VsZWN0Lmlzb3R5cGUsICIpIikpICsKICAgIGdlb21fcG9pbnQoKSArIAogICAgZ2VvbV9saW5lKGFlcyhncm91cD1zdWJqZWN0X2lkKSxsaW5ldHlwZSA9ICJkb3R0ZWQiKSsKICAgIGxhYnMoeCA9ICJEYXkgcG9zdCBib29zdCIsIHkgPSAiQWIgdGl0ZXIiKSArIAogICAgZ2VvbV9zbW9vdGgoKSArCiAgICB0aGVtZV9idygpICsKICAgIGZhY2V0X3dyYXAoLiB+IGFudGlnZW4sIHNjYWxlcyA9ICJmcmVlIiwgbnJvdyA9IDEpICsKICAgIHRoZW1lKHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIHN0cmlwLnBsYWNlbWVudCA9ICJvdXRzaWRlIikgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICdsb2cyJywgbGFiZWxzPXNjYWxlRlVOKQoKCnBsb3QocGxvdDEpCiNkZXYub2ZmKCkKI3BuZyhmaWxlbmFtZT1wYXN0ZTAoIjIwMjEiLHNlbGVjdC5pc290eXBlLCIucG5nIiksIHdpZHRoPTYwMCwgaGVpZ2h0PTcwMCkgIApwbG90MiA8LSBkYXRhXzIwMjFfY29tbW9uICU+JQogIGZpbHRlcihpc290eXBlID09IHNlbGVjdC5pc290eXBlLCBkcGIgPCA1MCkgJT4lCiAgZmlsdGVyKGFudGlnZW4gJWluJSBjKCJEVCIsICJGSEEiLCAiRklNMi8zIikpICAlPiUKICBmaWx0ZXIoYW50aWdlbiAlaW4lIHVuaXF1ZShkYXRhXzIwMjBfY29tbW9uW2RhdGFfMjAyMF9jb21tb24kaXNvdHlwZSA9PSBzZWxlY3QuaXNvdHlwZSxdJGFudGlnZW4pKSAlPiUKICAjZ2dwbG90KC4sIGFlcyh5PWxvZzIoYWJfdGl0ZXJfbWVkaWFuKSwgeD1kcGIpKSArCiAgZ2dwbG90KC4sIGFlcyh5PWFiX3RpdGVyX21lZGlhbiwgeD1kcGIpKSArCiAgICBnZ3RpdGxlKHBhc3RlMCgiMjAyMSBBbnRpYm9keSB0aXRlcnMgKCIgLCBzZWxlY3QuaXNvdHlwZSwgIikiKSkgKwogICAgZ2VvbV9wb2ludCgpICsgCiAgICBnZW9tX2xpbmUoYWVzKGdyb3VwPXN1YmplY3RfaWQpLGxpbmV0eXBlID0gImRvdHRlZCIpKwogICAgbGFicyh4ID0gIkRheSBwb3N0IGJvb3N0IiwgeSA9ICJBYiB0aXRlciIpICsgCiAgICBnZW9tX3Ntb290aCgpICsKICAgIHRoZW1lX2J3KCkgKwogICAgZmFjZXRfd3JhcCguIH4gYW50aWdlbiwgc2NhbGVzID0gImZyZWUiLCBucm93ID0gMSkgKwogICAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgc3RyaXAucGxhY2VtZW50ID0gIm91dHNpZGUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gJ2xvZzInLCBsYWJlbHM9c2NhbGVGVU4pCgoKcGxvdChwbG90MikKI2Rldi5vZmYoKQp9CgoKCgpgYGAKIyMgUGxvdGluZyBpbiBsb2cgc2NhbGUKYGBge3J9CmZvcihzZWxlY3QuaXNvdHlwZSBpbiBjKCJJZ0cxIiwgIklnRzIiLCAiSWdHMyIsICJJZ0c0IikpCnsKICAKI3BuZyhmaWxlbmFtZT1wYXN0ZTAoIjIwMjAiLHNlbGVjdC5pc290eXBlLCIucG5nIiksIHdpZHRoPTYwMCwgaGVpZ2h0PTcwMCkgIAogIAojc2VsZWN0Lmlzb3R5cGVfYW50aWdlbiA9ICJJZ0cxIiAKcGxvdDEgPC0gZGF0YV8yMDIwX2NvbW1vbiAlPiUKICBmaWx0ZXIoaXNvdHlwZSA9PSBzZWxlY3QuaXNvdHlwZSwgcGxhbm5lZF9kYXlfcmVsYXRpdmVfdG9fYm9vc3QgPCA1MCkgJT4lCiAgZmlsdGVyKGFudGlnZW4gJWluJSBjKCJPVkEiLCAiUFJOIiwgIlBUIiwgIlRUIikpICAlPiUKICBmaWx0ZXIoYW50aWdlbiAlaW4lIHVuaXF1ZShkYXRhXzIwMjFfY29tbW9uW2RhdGFfMjAyMV9jb21tb24kaXNvdHlwZSA9PSBzZWxlY3QuaXNvdHlwZSxdJGFudGlnZW4pKSAlPiUKICBnZ3Bsb3QoLiwgYWVzKHk9KGFiX3RpdGVyX21lZGlhbiksIHg9cGxhbm5lZF9kYXlfcmVsYXRpdmVfdG9fYm9vc3QpKSArCiAgICBnZ3RpdGxlKHBhc3RlMCgiMjAyMCBBbnRpYm9keSB0aXRlcnMgKCIgLCBzZWxlY3QuaXNvdHlwZSwgIikiKSkgKwogICAgZ2VvbV9wb2ludCgpICsgCiAgICBnZW9tX2xpbmUoYWVzKGdyb3VwPXN1YmplY3RfaWQpLGxpbmV0eXBlID0gImRvdHRlZCIpKwogICAgbGFicyh4ID0gIkRheSBwb3N0IGJvb3N0IiwgeSA9ICJBYiB0aXRlciIpICsgCiAgICBnZW9tX3Ntb290aCgpICsKICAgIHRoZW1lX2J3KCkgKwogICAgZmFjZXRfd3JhcCguIH4gYW50aWdlbiwgc2NhbGVzID0gImZyZWUiLCBucm93ID0gMSkgKwogICAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgc3RyaXAucGxhY2VtZW50ID0gIm91dHNpZGUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gJ2xvZzInLCBsYWJlbHM9c2NhbGVGVU4pCgoKcGxvdChwbG90MSkKI2Rldi5vZmYoKQojcG5nKGZpbGVuYW1lPXBhc3RlMCgiMjAyMSIsc2VsZWN0Lmlzb3R5cGUsIi5wbmciKSwgd2lkdGg9NjAwLCBoZWlnaHQ9NzAwKSAgCnBsb3QyIDwtIGRhdGFfMjAyMV9jb21tb24gJT4lCiAgZmlsdGVyKGlzb3R5cGUgPT0gc2VsZWN0Lmlzb3R5cGUsIGRwYiA8IDUwKSAlPiUKICBmaWx0ZXIoYW50aWdlbiAlaW4lIGMoIk9WQSIsICJQUk4iLCAiUFQiLCAiVFQiKSkgICU+JQogIGZpbHRlcihhbnRpZ2VuICVpbiUgdW5pcXVlKGRhdGFfMjAyMF9jb21tb25bZGF0YV8yMDIwX2NvbW1vbiRpc290eXBlID09IHNlbGVjdC5pc290eXBlLF0kYW50aWdlbikpICU+JQogICNnZ3Bsb3QoLiwgYWVzKHk9bG9nMihhYl90aXRlcl9tZWRpYW4pLCB4PWRwYikpICsKICBnZ3Bsb3QoLiwgYWVzKHk9YWJfdGl0ZXJfbWVkaWFuLCB4PWRwYikpICsKICAgIGdndGl0bGUocGFzdGUwKCIyMDIxIEFudGlib2R5IHRpdGVycyAoIiAsIHNlbGVjdC5pc290eXBlLCAiKSIpKSArCiAgICBnZW9tX3BvaW50KCkgKyAKICAgIGdlb21fbGluZShhZXMoZ3JvdXA9c3ViamVjdF9pZCksbGluZXR5cGUgPSAiZG90dGVkIikrCiAgICBsYWJzKHggPSAiRGF5IHBvc3QgYm9vc3QiLCB5ID0gIkFiIHRpdGVyIikgKyAKICAgIGdlb21fc21vb3RoKCkgKwogICAgdGhlbWVfYncoKSArCiAgICBmYWNldF93cmFwKC4gfiBhbnRpZ2VuLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAxKSArCiAgICB0aGVtZShzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAnbG9nMicsIGxhYmVscz1zY2FsZUZVTikKCgpwbG90KHBsb3QyKQojZGV2Lm9mZigpCn0KCgoKCmBgYApgYGB7cn0KCmRhdGFfcGxvdF8yMDIxX21lZGlhbnNfZDAgIDwtIGRhdGFfMjAyMSAlPiUKICBncm91cF9ieShpc290eXBlX2FudGlnZW4pICU+JQogIGZpbHRlcihkcGIgPT0gMCkgICU+JQogIHN1bW1hcmlzZShtZWRpYW5fZDAgPSBtZWRpYW4oYWJfdGl0ZXJfbWVkaWFuKSkKCmRhdGFfcGxvdF8yMDIxX21lZGlhbnNfZDAKYGBgCiMjIFBsb3QgdGFpbCBkaXN0cmlidXRpb24KCmBgYHtyfQpmb3Ioc2VsZWN0Lmlzb3R5cGUgaW4gYygiSWdHIikpCnsKICAKcDEgPC0gZGF0YV8yMDIwX2NvbW1vbiAlPiUKICAjZmlsdGVyKGFudGlnZW4gJWluJSB1bmlxdWUoZGF0YV8yMDIxX2NvbW1vbikpCiAgZmlsdGVyKGlzb3R5cGUgPT0gc2VsZWN0Lmlzb3R5cGUpICU+JQogIGFycmFuZ2UoZGVzYyhhYl90aXRlcl9tZWRpYW4pKSAlPiUKICBnZ3Bsb3QoYWVzKHk9YWJfdGl0ZXJfbWVkaWFuKSkgKyAgc3RhdF9lY2RmKGdlb20gPSAicG9pbnQiKSsKICBsYWJzKHkgPSAiQWIgdGl0ZXIiLCB4ID0gIlBlcmNlbnRpbGUiKSsgZ2d0aXRsZShwYXN0ZTAoIjIwMjAgQW50aWJvZHkgdGl0ZXJzICgiICwgc2VsZWN0Lmlzb3R5cGUsICIpIikpICsgdGhlbWVfYncoKSArCiAgZmFjZXRfd3JhcCguIH4gYW50aWdlbiwgc2NhbGVzID0gImZyZWUiLCBucm93ID0gMSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICdsb2cyJywgbGFiZWxzPXNjYWxlRlVOKQogIAogICNnZ3Bsb3QoYWVzKHg9YWJfdGl0ZXJfbWVkaWFuLCB5PVNhbXBsZV9JRCkpICsgIGdlb21fcG9pbnQoKQpwbG90KHAxKQoKCnAxIDwtIGRhdGFfMjAyMV9jb21tb24gJT4lCiAgI2ZpbHRlcihhbnRpZ2VuICVpbiUgdW5pcXVlKGRhdGFfMjAyMF9jb21tb24pKSAlPiUKICBmaWx0ZXIoYW50aWdlbiAlaW4lIHVuaXF1ZShkYXRhXzIwMjBfY29tbW9uW2RhdGFfMjAyMF9jb21tb24kaXNvdHlwZSA9PSBzZWxlY3QuaXNvdHlwZSxdJGFudGlnZW4pKSAlPiUKICBmaWx0ZXIoaXNvdHlwZSA9PSBzZWxlY3QuaXNvdHlwZSkgJT4lCiAgYXJyYW5nZShkZXNjKGFiX3RpdGVyX21lZGlhbikpICU+JQogIGdncGxvdChhZXMoeT1hYl90aXRlcl9tZWRpYW4pKSArICBzdGF0X2VjZGYoZ2VvbSA9ICJwb2ludCIpKwogIGxhYnMoeSA9ICJBYiB0aXRlciIsIHggPSAiUGVyY2VudGlsZSIpKyBnZ3RpdGxlKHBhc3RlMCgiMjAyMSBBbnRpYm9keSB0aXRlcnMgKCIgLCBzZWxlY3QuaXNvdHlwZSwgIikiKSkgKyB0aGVtZV9idygpICsKICBmYWNldF93cmFwKC4gfiBhbnRpZ2VuLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAxKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gJ2xvZzInLCBsYWJlbHM9c2NhbGVGVU4pCiAgCiAgI2dncGxvdChhZXMoeD1hYl90aXRlcl9tZWRpYW4sIHk9U2FtcGxlX0lEKSkgKyAgZ2VvbV9wb2ludCgpCnBsb3QocDEpCn0KCgpgYGAKCmBgYHtyfQpmb3Ioc2VsZWN0Lmlzb3R5cGUgaW4gYygiSWdHMSIsICJJZ0cyIiwgIklnRzMiLCAiSWdHNCIpKQp7CiAgCnAxIDwtIGRhdGFfMjAyMF9jb21tb24gJT4lCiAgI2ZpbHRlcihhbnRpZ2VuICVpbiUgdW5pcXVlKGRhdGFfMjAyMV9jb21tb24pKQogIGZpbHRlcihpc290eXBlID09IHNlbGVjdC5pc290eXBlKSAlPiUKICBhcnJhbmdlKGRlc2MoYWJfdGl0ZXJfbWVkaWFuKSkgJT4lCiAgZ2dwbG90KGFlcyh5PWFiX3RpdGVyX21lZGlhbikpICsgIHN0YXRfZWNkZihnZW9tID0gInBvaW50IikrCiAgbGFicyh5ID0gIkFiIHRpdGVyIiwgeCA9ICJQZXJjZW50aWxlIikrIGdndGl0bGUocGFzdGUwKCIyMDIwIEFudGlib2R5IHRpdGVycyAoIiAsIHNlbGVjdC5pc290eXBlLCAiKSIpKSArIHRoZW1lX2J3KCkgKwogIGZhY2V0X3dyYXAoLiB+IGFudGlnZW4sIHNjYWxlcyA9ICJmcmVlIiwgbnJvdyA9IDIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAnbG9nMicsIGxhYmVscz1zY2FsZUZVTikKICAKICAjZ2dwbG90KGFlcyh4PWFiX3RpdGVyX21lZGlhbiwgeT1TYW1wbGVfSUQpKSArICBnZW9tX3BvaW50KCkKcGxvdChwMSkKCnAyIDwtIGRhdGFfMjAyMV9jb21tb24gJT4lCiAgI2ZpbHRlcihhbnRpZ2VuICVpbiUgdW5pcXVlKGRhdGFfMjAyMF9jb21tb24pKSAlPiUKICBmaWx0ZXIoYW50aWdlbiAlaW4lIHVuaXF1ZShkYXRhXzIwMjBfY29tbW9uW2RhdGFfMjAyMF9jb21tb24kaXNvdHlwZSA9PSBzZWxlY3QuaXNvdHlwZSxdJGFudGlnZW4pKSAlPiUKICBmaWx0ZXIoaXNvdHlwZSA9PSBzZWxlY3QuaXNvdHlwZSkgJT4lCiAgYXJyYW5nZShkZXNjKGFiX3RpdGVyX21lZGlhbikpICU+JQogIGdncGxvdChhZXMoeT1hYl90aXRlcl9tZWRpYW4pKSArICBzdGF0X2VjZGYoZ2VvbSA9ICJwb2ludCIpKwogIGxhYnMoeSA9ICJBYiB0aXRlciIsIHggPSAiUGVyY2VudGlsZSIpKyBnZ3RpdGxlKHBhc3RlMCgiMjAyMSBBbnRpYm9keSB0aXRlcnMgKCIgLCBzZWxlY3QuaXNvdHlwZSwgIikiKSkgKyB0aGVtZV9idygpICsKICBmYWNldF93cmFwKC4gfiBhbnRpZ2VuLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gJ2xvZzInLCBsYWJlbHM9c2NhbGVGVU4pCiAgCiAgI2dncGxvdChhZXMoeD1hYl90aXRlcl9tZWRpYW4sIHk9U2FtcGxlX0lEKSkgKyAgZ2VvbV9wb2ludCgpCnBsb3QocDIpCn0KYGBgCgoKYGBge3J9CmRhdGFfMjAyMF9jb21tb24gJT4lCiAgZmlsdGVyKGlzb3R5cGUgIT0gIklnRSIgJiBwbGFubmVkX2RheV9yZWxhdGl2ZV90b19ib29zdD09MCkgJT4lCiAgbXV0YXRlKHRpdGVyID0gaWZfZWxzZShhYl90aXRlciA8PSBsb3dlcl9saW1pdF9vZl9kZXRlY3Rpb24sIDAsIGFiX3RpdGVyKSwKICAgICAgICAgdGl0ZXJfbG9kID0gaWZfZWxzZShhYl90aXRlciA8PSBsb3dlcl9saW1pdF9vZl9kZXRlY3Rpb24sIGxvd2VyX2xpbWl0X29mX2RldGVjdGlvbiwgYWJfdGl0ZXIpLAogICAgICAgICAgICkgJT4lCiAgZ3JvdXBfYnkoaXNvdHlwZV9hbnRpZ2VuKSAlPiUKICBzdW1tYXJpc2UobWVkaWFuX2xvZF9UPSBtZWRpYW4odGl0ZXJfbG9kKSwgbWVkaWFuX2xvZF9GPSBtZWRpYW4odGl0ZXJbdGl0ZXI+MF0pKQpgYGAKCgpgYGB7cn0KCmBgYAoK